/*
 * @Date: 2023-03-15 17:20:30
 * @LastEditTime: 2023-03-17 16:56:02
 * @FilePath: /hua-fei-chong-zhi/src/sdk/tronWeb.ts
 * 介绍:波场链sdk
 */
import { sdkSucceed, sdkFail, SdkRes } from "./index";
import { TronLinkAdapter } from "@tronweb3/tronwallet-adapters";
import type { TronWeb } from "tronweb.types";
import tronAbi from "./abi/tronAbi";
import BN from "bn.js";

const adapter = new TronLinkAdapter();
const tronweb = window.tronWeb as unknown as TronWeb & unknownObj;
/**连接钱包 */
export function sdkConnect() {
  return new Promise<SdkRes<string>>((resolve) => {
    try {
      if (!window.tronWeb) return resolve(sdkFail("请切换波场链后再尝试连接"));
      adapter
        .connect()
        .then(() => {
          resolve(sdkSucceed("连接钱包", adapter.address));
        })
        .catch((error) => {
          resolve(sdkFail(error.message, error));
        });
    } catch (error: any) {
      resolve(sdkFail("意料之外" + error.message, error));
    }
  });
}
export function sdkGetAddress(): string {
  return adapter.address!;
}

/**判断是否波场 */
export function sdkIsTron() {
  return Boolean(window.tronWeb);
}
/**
 * * 授权
 * @param omit 授权合约地址
 * @param amount 支付金额
 * @param format 精度
 * @param toAddress 授权地址
 * @param fromAddress 付款用户地址
 * @returns
 */
export function sdkApprove(
  omit: string,
  amount: number,
  format: number,
  toAddress: string
) {
  return new Promise<SdkRes<string>>((resolve) => {
    const value = parseIntAmount(amount, format, "*");
    console.log("授权");
    console.log("omit", omit);
    console.log("amount", amount);
    console.log("format", format);
    console.log("value", value);
    console.log("toAddress", toAddress);

    const contract = tronweb.contract(tronAbi as any, omit);
    let send: any;
    if (!contract.methods.increaseAllowance)
      send = contract.methods.approve(toAddress, value).send;
    else send = contract.methods.increaseAllowance(toAddress, value).send;
    send({
      feeLimit: 100000000,
    } as any)
      .then(sussend)
      .catch((error: any) => {
        resolve(sdkFail(error.message, error));
      });

    function sussend(res: string) {
      resolve(sdkSucceed("授权", res));
    }
  });
}
/**
 * * 发起代币转账
 * @param mint 合约地址
 * @param amount 付款金额
 * @param format 精度
 * @param toAddress 收款地址
 * @param fromAddress 付款地址
 */
export function sdkTransferToken(
  mint: string,
  amount: number,
  format: number,
  toAddress: string
) {
  return new Promise<SdkRes<string>>(async (resolve) => {
    const value = parseAmount(amount, format, "*");
    console.log("代币转账");
    console.log("amount", amount, "format", format, "value", value);
    console.log("mint", mint);
    console.log("toAddress", toAddress);
    const contract = tronweb.contract(tronAbi as any, mint);
    contract.methods
      .transfer(toAddress, value)
      .send()
      .then((res) => {
        resolve(sdkSucceed("代币转账", res));
      })
      .catch((error) => {
        console.log("代币转账");
        resolve(sdkFail(error.message || error, error));
      });
  });
}

/**金额精度调整-整数 */
function parseIntAmount(
  balance: number | string | void | null,
  format: number,
  mode: "*" | "/" = "/"
): string {
  if (!balance) return "0";
  const bTen = new BN(10);
  const bFormat = bTen.pow(new BN(format));
  const bBalance = new BN(balance);
  if (mode == "/") return bBalance.div(bFormat).toString();
  return bBalance.mul(bFormat).toString();
}

/**金额精度调整 */
function parseAmount(
  balance: number | string | void | null,
  format: number,
  mode: "*" | "/" = "/"
): string {
  if (!balance) return "0";
  const cause = Math.pow(10, 8);
  balance = Number(balance) * cause;
  const formatNumber = new BN(10).pow(new BN(format));
  if (mode == "/")
    return new BN(balance).div(formatNumber).div(new BN(cause)).toString();
  return new BN(balance).mul(formatNumber).div(new BN(cause)).toString();
}
